home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / source / music4c.sit / Music4C Folder / Sources Folder / PrepScore.c < prev    next >
Text File  |  1990-08-07  |  28KB  |  1,244 lines

  1. /*
  2. * ⌐ Graeme Gerrard 1990
  3. * Faculty of Music, University of Melbourne
  4. * Parkville Victoria 3052 Australia.
  5. *
  6. * ARPANET: grae@murdu.ucs.unimelb.edu.au
  7. * telephone: (613) 344 4127, Fax: (613) 344 5346
  8. */
  9.  
  10. #include    "Music4C.h"
  11. #include    <unix.h>
  12. #include     "ErrorAlert.h"
  13.  
  14.  
  15. int    read_section(void);
  16. extern    void    Report(char *);
  17. extern    Event    *warp_tempo(double *, Event *);
  18. extern    void    renumber(Event *);
  19. void    add_end_ops(Event *);
  20. void    report2(Event *);
  21. void    fwrite2(Event *);
  22. extern    Boolean    MAC_Check_Pass12_Events(int, int);
  23.  
  24. extern    void    PstringCopy(char *, char *);
  25. extern    void    PstringCat(char *, char *);
  26. Boolean    getcard(void);
  27. void    parse_card(void);
  28. void    report1(int, char *, double *);
  29. Event    *insert_in_list(int, int, double *, Event *);
  30. int        decode(void);
  31. int        decode_t_card(int);
  32. void    set_output(void);
  33. int        straight_copy(void);
  34. int        straight_I_copy(void);
  35. double    myAtof(char    *);
  36. void    check_event(Event *);
  37. void    write2_check(Event *);
  38. void    check_list(Event *);
  39.  
  40. FILE    *p2out;
  41. Str255    p2tmp;
  42. int        tempo_change;
  43. static    int        lineno;
  44. static    int        ncards;
  45. static    int        n_i_cards;
  46. static    int        sectno;
  47. extern    double    srate;
  48. static    char        card[MAXCARD];
  49. static    int        op;
  50. static    int        prevop;
  51. static    double    instr_group;
  52. static    int        previnstr_group;
  53. static    int        nargs;
  54. static    double    latest_time;
  55. static    double    params[MAXPARAMS];
  56. double    *tparams[MAX_TEMPO_CARDS];
  57. int        totalcards;
  58. int        totalIcards;
  59. int        n_T_cards;
  60. Event     *list;
  61. extern    double    TotalDuration;
  62. extern    int    max_ins_types;
  63. OSErr    errnum;
  64. static    Boolean    EcardRead;
  65. char        aString1[256];
  66. char        aString2[256];
  67.  
  68. extern    Str255    theMess1, theMess2;
  69. double    atof();
  70.  
  71. void    prepare_score(void);
  72. extern    void    Pcheck_list(Event *);
  73.  
  74. Boolean        FileFinished;
  75.  
  76. void    prepare_score()
  77. {
  78.  
  79.     register int i;
  80.     extern    int    out1_flag, out2_flag;
  81.     extern    int    RunToPass1, RunToPass2, RunToPass3, CreateSoundFile;
  82.     long        fTicks;
  83.  
  84.  
  85.     lineno = 1;
  86.     ncards = 0;
  87.     totalcards = 0;
  88.     totalIcards = 0;
  89.     TotalDuration = 0.0;
  90.     list = NIL;
  91.     sectno = 1;
  92.     max_ins_types = 0;
  93.     latest_time = 0.0;
  94.     EcardRead = FALSE;
  95.  
  96.     if ( RunToPass2 || RunToPass3 || CreateSoundFile) { /* open pass2 out file */
  97.         Delay(0L, &fTicks);
  98.         NumToString(fTicks, &aString1);
  99.         PtoCstr((char *)aString1);
  100.         strcpy((char *)p2tmp, "-p2tmp.");
  101.         strcat((char *)p2tmp, aString1);
  102.         p2out = fopen((char *)p2tmp, "w+");
  103.     }
  104.     FileFinished = FALSE;
  105.     while ( !FileFinished ) {
  106.         tempo_change = 0;
  107.         n_T_cards = 0;
  108.         while ( ncards = read_section() ) {
  109.             if ( out1_flag ) {
  110.                 sprintf((char *)theMess1, "End Pass1 of Section %d\n", sectno);
  111.                 Report((char *)theMess1);
  112.                 Report("--------------------------------------\n");
  113.             }
  114.             totalcards += ncards;
  115.             if ( out2_flag ) {
  116.                 sprintf((char *)theMess1, "Pass2 output score for Section No. %d\n", sectno);
  117.                 Report((char *)theMess1);
  118.             }
  119.             if ( RunToPass2 || RunToPass3 || CreateSoundFile) {
  120.                 if ( tempo_change && ncards >= 2 ) {
  121.                     for ( i = 0; i < n_T_cards; i++) {
  122.                         list = warp_tempo(tparams[i], list);
  123.                     }
  124.                 }
  125.                 if ( ncards >= 2 ) {
  126.                     renumber(list);
  127.                 }
  128.                 add_end_ops(list);
  129.                 if ( out2_flag )
  130.                     report2(list);
  131.                 fwrite2(list);
  132.                 if ( out2_flag ) {
  133.                     sprintf((char *)theMess1, "End Pass2 of Section %d\n", sectno);
  134.                     Report((char *)theMess1);
  135.                     Report("--------------------------------------\n");
  136.                 }
  137.                 MAC_Check_Pass12_Events(2, sectno);
  138.             }
  139.             list = NIL;
  140.             for ( i = 0; i < n_T_cards; i++)
  141.                 DisposPtr((Ptr)tparams[i]);
  142.             n_T_cards = 0;
  143.             sectno++;
  144.         }
  145.     }
  146.     if (!EcardRead) {
  147.         PstringCopy((char *)theMess1, "\pNo end card in input file");
  148.         OSError(theMess1, NIL, NIL);
  149.     }
  150. }    /* prepare_score */
  151.  
  152.  
  153. read_section()
  154. {
  155.     int k;
  156.     Boolean    NewSection;
  157.     extern    int    out1_flag;
  158.     extern    int    RunToPass1;
  159.  
  160.     card[0] = '\0';
  161.     instr_group = 0.0;
  162.     previnstr_group = 0;
  163.     prevop = 0;
  164.     n_i_cards = 0;
  165.     ncards = 0;
  166.     NewSection = TRUE;
  167.     
  168.     while ( (k = getcard())) {
  169.         if ( out1_flag &&     NewSection) {
  170.             NewSection = FALSE;
  171.             sprintf((char *)theMess1, "Pass1 output for Section %d\n", sectno);
  172.             Report((char *)theMess1);
  173.         }
  174.         ncards++;
  175.         parse_card();
  176.         if ( out1_flag )
  177.             report1(op, card, params);
  178.         if ( !RunToPass1 ) {
  179.             if ( op == FOP || op == IOP || op == SOP || op == EOP)
  180.                     list = insert_in_list(op, nargs, params, list);
  181.         }
  182.         prevop = op;
  183.         if ( op == SOP || op == EOP )
  184.             break;
  185.         MAC_Check_Pass12_Events(1, sectno);
  186.     }
  187.     totalIcards += n_i_cards;
  188.     return(ncards);
  189. }
  190.  
  191.  
  192. Boolean    getcard()
  193. {
  194.     char    buffer[1];
  195.     char    *cp;
  196.     int        ch;
  197.     OSErr    theErr;
  198.     register    int    i;
  199.     extern        int    scoreRefNum;
  200.     long        count;
  201.  
  202.     card[0] = '\0';
  203.     i = 0;
  204.     cp = card;
  205.     count = 1L;
  206.     while( (theErr = FSRead(scoreRefNum, &count, &buffer)) == noErr) {
  207.         if ( *buffer  == ';' )
  208.             break;
  209.         if (theErr == eofErr || count == 0L ) {
  210.             FileFinished = TRUE;
  211.             break;
  212.         }
  213.  
  214.         *cp = buffer[0];
  215.         if ( *cp == ';')
  216.             break;
  217.         if ( isspace(*cp) ){
  218.             if ( *cp == '\n' || *cp == '\r'  ) {
  219.                 ++lineno;
  220.                 if ( i == 0 ) { /* start of card */
  221.                     *cp = '\0';
  222.                 }
  223.                 else {        /* in a card */
  224.                     *cp++ = ' ';
  225.                     i++;
  226.                 }
  227.             }
  228.             else {
  229.                 if ( i == 0 ) /* start of card */
  230.                     *cp = '\0';
  231.                 else {
  232.                     cp++;
  233.                     i++;
  234.                 }
  235.             }
  236.         }
  237.         else { /* not a space */
  238.             cp++;
  239.             i++;
  240.         }
  241.         if ( i >= MAXCARD ) {
  242.             PstringCopy((char *)theMess1, "\pAn input line is too long, check for omitted record teminator ';'");
  243.             OSError(theMess1, NIL, NIL);
  244.         }
  245.     }
  246.     *cp = '\0';
  247.     if ( isupper(card[0]) )
  248.         card[0] += 0x20;
  249.     if ( card[0] == '\0' || theErr == eofErr || count == 0L ) {
  250.         FileFinished = TRUE;
  251.         return(FALSE);
  252.     }
  253.     else {
  254.         return(TRUE);
  255.     }
  256. }    /* getcard */
  257.  
  258.  
  259. void parse_card()
  260. {
  261.     
  262.     register    int    i;
  263.     extern    int    nchnls;
  264.     extern    double    rescalingConst;
  265.     if (!isalpha(card[0])) {
  266.         sprintf((char *)theMess1, "Opcode error on line %d", lineno);
  267.         OSError(theMess1, NIL, NIL );
  268.     }
  269.  
  270.     switch( card[0] ) {
  271.         case 'i':
  272.         case 'I':
  273.             op = IOP;
  274.             nargs = decode();
  275.             instr_group = params[0];
  276.             previnstr_group = (int)instr_group;
  277.             n_i_cards++;
  278.             if ( instr_group > max_ins_types )
  279.                 max_ins_types = instr_group;
  280.             if ( latest_time < ( params[2] + params[3] ))
  281.                 latest_time = ( params[2] + params[3] );
  282.             
  283.             /*latest_time = MAX(latest_time, params[2] + params[3] );*/
  284.             break;
  285.         case 'f':
  286.         case 'F':
  287.             op = FOP;
  288.             nargs = decode();
  289.             previnstr_group = 0;
  290.         if ( latest_time < params[1] )
  291.                 latest_time = params[1];
  292.         
  293.             /*latest_time = MAX(latest_time, params[1] );*/
  294.             break;
  295.         case 's':
  296.         case 'S':
  297.             op = SOP;
  298.             params[0] = 0.0;
  299.             params[1] = 0.0;
  300.             nargs = decode();
  301.             previnstr_group = 0;
  302.             if ( nargs > 1 ) {
  303.                 NumToString((long)sectno, aString2);
  304.                 PstringCopy((char *)theMess2, "\pSection no: ");
  305.                 PstringCat((char *)theMess2, (char *)aString2);
  306.                 PstringCopy((char *)theMess1, "\pToo many arguments in section card");
  307.                 OSError(theMess1, theMess2, NIL);
  308.             }
  309.  
  310.             if ( params[0] <= 0.0 )
  311.                 params[0] = latest_time;
  312.             else {
  313.                 if ( params[0] < latest_time ) {
  314.                     NumToString((long)sectno, aString2);
  315.                     PstringCopy((char *)theMess2,"\pSection no: ");
  316.                     PstringCat((char *)theMess2, (char *)aString2);
  317.                     PstringCopy((char *)theMess1,"\pEnd time of section is greater than indicated duration");
  318.                     OSError(theMess1, theMess2, NIL);
  319.                     
  320.                 }
  321.             }
  322.             /* shift end time to p1 for easier comparisions in pass2 */
  323.             nargs++;
  324.             params[1] = params[0];
  325.             latest_time = 0.0;
  326.             break;
  327.         case 'e':
  328.         case 'E':
  329.             op = EOP;
  330.             EcardRead = TRUE;
  331.             params[0] = 0.0;
  332.             params[1] = 0.0;
  333.             nargs = decode();
  334.             previnstr_group = 0;
  335.             /* p0 = end time, p1 = nchnls, [p2 = sr] [p3 = rescaling constant ]*/
  336.             if ( nargs > 4 ) {
  337.                 PstringCopy((char *)theMess1,"\pToo many arguments on 'e' record");
  338.                 OSError(theMess1, NIL, NIL);
  339.             }
  340.             if ( params[1] > MAXCHANS || params[1] < 1.0 ) {
  341.                 PstringCopy((char *)theMess1,"\pError in number of output channels on 'e' record");
  342.                 PstringCopy((char *)theMess2,"\pMust be 1, 2 or 4");
  343.                 OSError(theMess1, theMess2, NIL);
  344.             }
  345.             nchnls = (int) params[1];
  346.             if (params[2] <= 0.0 )
  347.                 srate = SRATE;
  348.             else
  349.                 srate = params[2];
  350.             
  351.             rescalingConst = 0.0;
  352.             if ( nargs > 3 )
  353.                 rescalingConst = params[3];
  354.             else
  355.                 params[3] = 0.0;
  356.                 
  357.             if ( params[0] <= 0.0 )
  358.                 params[0] = latest_time;
  359.             else {
  360.                 if ( params[0] < latest_time ) {
  361.                     NumToString((long)sectno, aString2);
  362.                     PstringCopy((char *)theMess2,"\pSection no: ");
  363.                     PstringCat((char *)theMess2, (char *)aString2);
  364.                     PstringCopy((char *)theMess1,"\pEnd time of section is greater than indicated duration");
  365.                     OSError(theMess1, theMess2, NIL);
  366.                 }
  367.                 latest_time = params[0];
  368.             }
  369.             /* shift end time to p1 for easier comparisions in pass2 */
  370.             nargs++;
  371.             params[4] = params[3];
  372.             params[3] = params[2];
  373.             params[2] = params[1];
  374.             params[1] = params[0];
  375.             params[0] = 0.0;
  376.             break;
  377.         case 't':
  378.         case 'T':
  379.             if ( n_T_cards >= MAX_TEMPO_CARDS) {
  380.                 NumToString((long)sectno, aString2);
  381.                 PstringCopy((char *)theMess2,"\pSection no: ");
  382.                 PstringCat((char *)theMess2, (char *)aString2);
  383.                 PstringCopy((char *)theMess1,"\pToo many tempo cards");
  384.                 OSError(theMess1, theMess2, NIL);
  385.             }
  386.             op = TOP;
  387.             tempo_change = 1;
  388.             tparams[n_T_cards] = (double *)NewPtr(sizeof(double) * MAXPARAMS);
  389.             if ( (errnum = MemError())  != noErr ){
  390.                 PstringCopy((char *)theMess1,"\pError allocating memory in parse_card for tempo_card");
  391.                 OSError(theMess1, NIL, NIL);
  392.             }
  393.             /* zero fields of card */
  394.             for ( i = 0; i < MAXPARAMS; i++ ) 
  395.                 *(tparams[n_T_cards]+i) = 0.0;
  396.             nargs = decode_t_card(n_T_cards);
  397.             n_T_cards++;
  398.             break;
  399.         case 'c':
  400.         case 'C':
  401.         case '!':
  402.             op = COP;
  403.             previnstr_group = 0;
  404.             break;
  405.         case 'o':
  406.         case 'O':
  407.             op = OOP;
  408.             nargs = decode();
  409.             previnstr_group = 0;
  410.             set_output();
  411.             break;
  412.         default:
  413.             NumToString((long)lineno, aString2);
  414.             PstringCopy(aString1, "\pon line ");
  415.             PstringCat(aString1, aString2);
  416.                 PstringCat((char *)theMess2, (char *)aString1);
  417.                 PstringCopy((char *)theMess1,"\pUnknown opcode");
  418.                 OSError(theMess1, theMess2, NIL);
  419.             break;            
  420.     }
  421. }    /* parse_card */
  422.  
  423. int    decode()
  424. {
  425.     register int i;
  426.     char *cp;
  427.     
  428.     cp = card;
  429.  
  430.     cp++;
  431.     if ( op != IOP ) {
  432.         return(straight_copy());
  433.     }
  434.      if ( n_i_cards < 1 || prevop != op) {
  435.         return(straight_I_copy());
  436.     }
  437.  
  438.     /* check for same instr_group */
  439.     while (*cp && isspace(*cp))
  440.         cp++;
  441.     if ( *cp == CARRY_CODE ) {
  442.         instr_group = (double)previnstr_group;
  443.     }
  444.     else if ( isdigit(*cp) ) {
  445.         instr_group = atof(cp);
  446.         if ( (int)instr_group != previnstr_group) {
  447.             return(straight_I_copy());
  448.         }
  449.     }
  450.     else {    /* error, not a number or a CARRY_CODE */
  451.         NumToString((long)lineno, aString2);
  452.         PstringCopy(aString1, "\pon line: ");
  453.         PstringCat(aString1, aString2);
  454.         PstringCat((char *)theMess2, (char *)aString1);
  455.         PstringCopy((char *)theMess1,"\pIllegal character in instrument number");
  456.         OSError(theMess1, theMess2, NIL);
  457.     }
  458.  
  459. /* we only get here if we may have to do carries */
  460.     params[0] = instr_group;
  461.     params[1] = 1.0;    /* save for instrument number */
  462.     cp++;
  463.     while (*cp && !isspace(*cp))
  464.         cp++;
  465.     while (isspace(*cp))
  466.         cp++;
  467.     for ( i = 2; i < MAXPARAMS && *cp; i++) {
  468.         if (isdigit(*cp) || *cp == '.' || *cp == '-' || *cp == '+') {
  469.             params[i] = myAtof(cp);
  470.         }
  471.         else if ( *cp == ';' )
  472.             /* pass */
  473.                 ;
  474.         else if (*cp == '*') {
  475.         /* do nothing, old value in params */
  476.         }
  477.         while (*cp && !isspace(*cp)) /* skip rest of number */
  478.             cp++;
  479.         while (*cp && isspace(*cp))    /* skip to start of next number */
  480.             cp++;
  481.         if (!*cp) {
  482.             previnstr_group = (int)params[0];
  483.             return(nargs);
  484.         }
  485.     }
  486. }    /* decode */
  487.  
  488.  
  489.  
  490. straight_I_copy()
  491. {
  492.     register int i;
  493.     char *cp;
  494. /* params format for i cards is:
  495. *    params[0] = instr_group for i cards, fno for fcards.
  496. *    params[1] = (unused for i cards, later becomes instrument NUMBER, otherwise
  497.     (start time)
  498. *    params[2] = start time for i cards, gen no for f cards
  499. *    params[3] = duration for i cards
  500. */
  501.     cp = card;
  502.     nargs = 0;
  503.     cp++;
  504.     while (isspace(*cp))
  505.         cp++;
  506.     if (isdigit(*cp) || *cp == '.' || *cp == '-' || *cp == '+') {
  507.         params[0] = myAtof(cp);
  508.         nargs++;
  509.         cp++;
  510.         while (*cp && !isspace(*cp)) /* skip rest of number */
  511.             cp++;
  512.         while (*cp && isspace(*cp))    /* skip to start of next number */
  513.             cp++;
  514.     }
  515.     params[1] = 1.0; 
  516.     nargs++;
  517.     while (isspace(*cp))
  518.         cp++;
  519.     for ( i = 2; i < MAXPARAMS && *cp; i++) {
  520.         if (isdigit(*cp) || *cp == '.' || *cp == '-' || *cp == '+') {
  521.             params[i] = myAtof(cp);
  522.             nargs++;
  523.         }
  524.         else if (*cp == CARRY_CODE) {
  525.             NumToString((long)lineno, aString2);
  526.             PstringCopy(aString1, "\pon line: ");
  527.             PstringCat(aString1, aString2);
  528.             PstringCat((char *)theMess2, (char *)aString1);
  529.             PstringCopy((char *)theMess1,"\pIllegal carry");
  530.             OSError(theMess1, theMess2, NIL);
  531.         }
  532.         else if ( *cp == ';' )
  533.             /* pass */
  534.                 ;
  535.         else {
  536.             NumToString((long)lineno, aString2);
  537.             PstringCopy(aString1, "\pon line: ");
  538.             PstringCat(aString1, aString2);
  539.             PstringCat((char *)theMess2, (char *)aString1);
  540.             PstringCopy((char *)theMess1,"\pIllegal character");
  541.             OSError(theMess1, theMess2, NIL);
  542.             
  543.         }
  544.         while (*cp && !isspace(*cp)) /* skip rest of number */
  545.             cp++;
  546.         while (*cp && isspace(*cp))    /* skip to start of next number */
  547.             cp++;
  548.         if (!*cp) {
  549.             previnstr_group = (int)params[0];
  550.             return(nargs);
  551.         }
  552.     }
  553.     return(nargs);
  554. }    /* straight_I_copy */
  555.  
  556.  
  557. int    straight_copy()
  558. {
  559.     register int i, k;
  560.     char *cp;
  561. /* params format for i cards is:
  562. *    params[0] = instr_group for i cards, fno for fcards.
  563. *    params[1] = (unused for i cards, later becomes instrument NUMBER, otherwise
  564.     (start time)
  565. *    params[2] = start time for i cards, gen no for f cards
  566. *    params[3] = duration for i cards
  567. */
  568.  
  569.     cp = card;
  570.     nargs = 0;
  571.     cp++;
  572.     while (isspace(*cp))
  573.         cp++;
  574.     for ( i = 0; i < MAXPARAMS && *cp; i++) {
  575.         if (isdigit(*cp) || *cp == '.' || *cp == '-' || *cp == '+') {
  576.             params[i] = myAtof(cp);
  577.             nargs++;
  578.         }
  579.         else if (*cp == CARRY_CODE) {
  580.             NumToString((long)lineno, aString2);
  581.             PstringCopy(aString1, "\pon line: ");
  582.             PstringCat(aString1, aString2);
  583.             PstringCat((char *)theMess2, (char *)aString1);
  584.             PstringCopy((char *)theMess1,"\pIllegal carry");
  585.             OSError(theMess1, theMess2, NIL);
  586.         }
  587.         else if ( *cp == ';' )
  588.             /* pass */
  589.                 ;
  590.         else {
  591.             NumToString((long)lineno, aString2);
  592.             PstringCopy(aString1, "\pon line: ");
  593.             PstringCat(aString1, aString2);
  594.             PstringCat((char *)theMess2, (char *)aString1);
  595.             PstringCopy((char *)theMess1,"\pIllegal character");
  596.             OSError(theMess1, theMess2, NIL);
  597.         }
  598.         while (*cp && !isspace(*cp)) /* skip rest of number */
  599.             cp++;
  600.         while (*cp && isspace(*cp))    /* skip to start of next number */
  601.             cp++;
  602.         if (!*cp) {
  603.             previnstr_group = (int)params[0];
  604.             return(nargs);
  605.         }
  606.     }
  607.     return(nargs);
  608. }    /* straight_copy */
  609.  
  610.  
  611.  
  612. int    decode_t_card(n_T_cards)
  613.     int    n_T_cards;
  614. {
  615.     register int i;
  616.     char *cp = card;
  617.  
  618.     nargs = 0;
  619.     cp++;
  620.     while (isspace(*cp))
  621.         cp++;
  622.     for ( i = 0; i < MAXPARAMS && *cp; i++) {
  623.         if (isdigit(*cp) || *cp == '.' || *cp == '-' || *cp == '+') {
  624.             *(tparams[n_T_cards]+i) = myAtof(cp);
  625.             nargs++;
  626.         }
  627.         else if ( *cp == ';' )
  628.             /* pass */
  629.                 ;
  630.         else {
  631.             sprintf((char *)aString1, "Section no %d line %d", sectno, lineno);
  632.             CtoPstr(aString1);
  633.             PstringCat((char *)theMess2, aString1);
  634.             PstringCat((char *)theMess1, "\pIllegal character in tempo record");
  635.             OSError(theMess1, theMess2, NIL);
  636.         }
  637.         while (*cp && !isspace(*cp)) /* skip rest of number */
  638.             cp++;
  639.         while (*cp && isspace(*cp))    /* skip to start of next number */
  640.             cp++;
  641.         if (!*cp) {
  642.             return(nargs);
  643.         }
  644.     }
  645. }    /* decode_t_card */
  646.  
  647.  
  648.  
  649. void    report2(list)
  650.     Event *list;
  651. {
  652.     /* prints event list on file for debugging purposes */
  653.  
  654.     Event *cursor;
  655.     register int i;
  656.     register int n;
  657.  
  658.  
  659.     if ( list == NIL ) {
  660.         return;
  661.     }
  662.     cursor = list;
  663.     while ( cursor != NIL ) { 
  664.         n = 0;
  665.         if ( cursor->op == ENDOP ) {
  666.             sprintf( (char *)theMess1,  "%d", (int)cursor->op);
  667.             Report((char *)theMess1);
  668.             sprintf( (char *)theMess1, " %8.3f", *(cursor->pptr));
  669.             Report((char *)theMess1);
  670.             sprintf( (char *)theMess1, " %8.3f", *(cursor->pptr+1));
  671.             Report((char *)theMess1);
  672.             sprintf( (char *)theMess1, "          %8.3f", *(cursor->pptr+2));
  673.             Report((char *)theMess1);
  674.         }
  675.         else {
  676.             sprintf( (char *)theMess1, " %d", cursor->op);
  677.             Report((char *)theMess1);
  678.             if ( cursor->op == EOP ) {
  679.                 sprintf( (char *)theMess1, " %8.3f", *(cursor->pptr+1) );
  680.                 Report((char *)theMess1);
  681.                 sprintf( (char *)theMess1, " %8.1f", *(cursor->pptr+2) );
  682.                 Report((char *)theMess1);
  683.                 sprintf( (char *)theMess1, " %8.1f", *(cursor->pptr+3) );
  684.                 Report((char *)theMess1);
  685.             }
  686.             else if ( cursor->op == SOP ) {
  687.                 sprintf( (char *)theMess1, " %8.3f", *(cursor->pptr) );
  688.                 Report((char *)theMess1);
  689.             }
  690.  
  691.             else {
  692.                 for ( i = 0; i < cursor->nargs; i++) {
  693.                     n++;
  694.                     sprintf((char *)theMess1, " %8.3f", *(cursor->pptr+i));
  695.                     Report((char *)theMess1);
  696.                     if ( n % 8 == 0 ) {
  697.                         if ( i < cursor->nargs-1) {
  698.                             Report("\n");
  699.                             Report("\t");
  700.                         }
  701.                     }
  702.                 }
  703.             }
  704.         }
  705.         Report("\n");
  706.         cursor = cursor->next;    /* get next element */
  707.     }
  708. }    /* report2 */
  709.  
  710.  
  711.  
  712. void    check_event(event)
  713.     Event *event;
  714. {
  715.     /* prints event list on terminal for debugging purposes */
  716.  
  717.     register int i;
  718.     register int n;
  719.  
  720.  
  721.     if ( !out1_flag)
  722.         return;
  723.     if ( event == NIL ) {
  724.         Report("null event\n");
  725.         return;
  726.     }
  727.         n = 0;
  728.         sprintf( (char *)theMess1, "%d", event->op);
  729.         Report((char *)theMess1);
  730.         sprintf( (char *)theMess1, " %d", event->nargs);    
  731.         Report((char *)theMess1);
  732.         for ( i = 0; i< event->nargs; i++) {
  733.             n++;
  734.             sprintf( (char *)theMess1, " %8.3f", *(event->pptr+i));    
  735.             Report((char *)theMess1);
  736.             if ( n % 8 == 0 ) {
  737.                 if ( i < event->nargs-1) {
  738.                     Report("\n");
  739.                     Report("\t");
  740.                 }
  741.             }
  742.         }
  743.         Report("\n");
  744. }    /* check_event */
  745.  
  746.  
  747. void    fwrite2(list)
  748.     Event *list;
  749. {
  750.     register    int    i;
  751.     register    int    k;
  752.     Event *cursor, *c;
  753.     int lastop;
  754.     extern int RunToPass1;
  755.     int    eventNo = 0;
  756.     int opcode;
  757.     cursor = list;
  758.     while ( cursor != NIL ) {
  759.         eventNo++;
  760.         lastop  = cursor->op;
  761.         switch (cursor->op ) {
  762.             case SOP:
  763.                 TotalDuration += *(cursor->pptr);
  764.                 i = fwrite(&cursor->op, sizeof(int), 1, p2out);
  765.                 i = fwrite(cursor->pptr, sizeof(double), 1, p2out);
  766.                 break;
  767.             case EOP:
  768.                 TotalDuration += *(cursor->pptr+1);
  769.                 i = fwrite(&cursor->op, sizeof(int), 1, p2out);
  770.                 i = fwrite(cursor->pptr, sizeof(double), 1, p2out);
  771.                 break;
  772.             case ENDOP:
  773.                 i = fwrite(&cursor->op, sizeof(int), 1, p2out);
  774.                 i = fwrite(cursor->pptr, sizeof(double), 3, p2out);
  775.                 break;
  776.             case IOP:
  777.                 if ( *(cursor->pptr+3) <= 0.0) {
  778.                     sprintf((char *)aString1, "Event %d has a duration of zero", eventNo);
  779.                     CtoPstr((char *)aString1);
  780.                     OSError(theMess1, NIL, NIL);
  781.                 }
  782.             case FOP:
  783.                 i = fwrite(&cursor->op, sizeof(int), 1, p2out);
  784.                 i = fwrite(&cursor->nargs, sizeof(int), 1, p2out);
  785. /*                for ( i = 0; i< cursor->nargs; i++)*/
  786.             k = fwrite(cursor->pptr, sizeof(double), cursor->nargs, p2out);
  787.                 break;
  788.         }
  789.         c = cursor;
  790.         cursor = cursor->next;
  791.         /* clean the list */
  792.         for ( i = 0; i < c->nargs; i++ ) {
  793.             DisposPtr((Ptr)c->pptr+i);
  794.         }
  795.         DisposPtr((Ptr)c);
  796.     }
  797.  
  798. /*    if ( lastop == EOP ) {
  799.         fclose(p2out);
  800.     }
  801. */
  802. } /* fwrite2 */
  803.  
  804. void    write2_check(list)
  805.     Event *list;
  806. {
  807.     register    int    i;
  808.     Event *cursor, *c;
  809.     int lastop;
  810.  
  811.  
  812.     if ( !out2_flag)
  813.         return;
  814.     Report("Output from write2_check\n");
  815.     cursor = list;
  816.     while ( cursor != NIL ) {
  817.         lastop  = cursor->op;
  818.         switch (cursor->op ) {
  819.             case SOP:
  820.             case EOP:
  821.                 sprintf( (char *)theMess1, "%d", cursor->op);    Report((char *)theMess1);
  822.                 sprintf( (char *)theMess1, "  %f", *(cursor->pptr));    Report((char *)theMess1);
  823.                 break;
  824.             case ENDOP:
  825.                 sprintf( (char *)theMess1, "  %d", cursor->op);    Report((char *)theMess1);
  826.                 sprintf( (char *)theMess1, "  %lf", *(cursor->pptr));    Report((char *)theMess1);
  827.                 sprintf( (char *)theMess1, "  %lf", *(cursor->pptr+1));    Report((char *)theMess1);
  828.                 sprintf( (char *)theMess1, "  %lf", *(cursor->pptr+2));    Report((char *)theMess1);
  829.                 break;
  830.             case IOP:
  831.             case FOP:
  832.                 sprintf( (char *)theMess1, "%d", cursor->op);    Report((char *)theMess1);
  833.                 sprintf( (char *)theMess1, "  %lf", *(cursor->pptr));    Report((char *)theMess1);
  834.                 sprintf( (char *)theMess1, "  %lf", *(cursor->pptr+1));    Report((char *)theMess1);
  835.                 sprintf( (char *)theMess1, "  %lf", *(cursor->pptr+2));    Report((char *)theMess1);
  836.                 sprintf( (char *)theMess1, "  %lf", *(cursor->pptr+3));    Report((char *)theMess1);
  837.                 sprintf( (char *)theMess1, "    nargs = %d", cursor->nargs );    Report((char *)theMess1);
  838.                 break;
  839.         }
  840.         Report("\n");
  841.         Report("---------------------------\n");
  842.         cursor = cursor->next;
  843.     }
  844. } /* write2_check */
  845.  
  846. void    set_output()
  847. {
  848.     extern    out1_flag;
  849.     extern    out2_flag;
  850.     extern    out3_flag;
  851.  
  852.     if ( nargs < 2 ) {
  853.         NumToString((long)lineno, aString2);
  854.         PstringCopy(aString1, "\pon line ");
  855.         PstringCat(aString1, aString2);
  856.         PstringCopy((char *)theMess2, aString1);
  857.         PstringCopy((char *)theMess1, "\pNot enough arguments on 'o' card");
  858.         OSError(theMess1, theMess2, NIL);
  859.         
  860.     }
  861.     if ( (int)params[0] == 1 ) {
  862.         if ( (int)params[1] > 0 )
  863.             out1_flag = 1;
  864.         else
  865.             out1_flag = 0;
  866.     }
  867.     else if ( (int)params[0] == 2 ) {
  868.         if ( (int)params[1] > 0 )
  869.             out2_flag = 1;
  870.         else
  871.             out2_flag = 0;
  872.     }
  873.     else if ( (int)params[0] == 3 ) {
  874.         if ( (int)params[1] > 0 )
  875.             out3_flag = 1;
  876.         else
  877.             out3_flag = 0;
  878.     }
  879. }    /* set_output */
  880.  
  881.  
  882. void    report1(op, card, p)
  883.     int     op;
  884.     char    card[];
  885.     double    p[];
  886. {
  887.     register int i;
  888.     register int n;
  889.     char *cp = card;
  890.  
  891.  
  892.  
  893.     if ( !out1_flag ) 
  894.         return;
  895.     if ( op == COP ) {
  896.         i = 0;
  897.         while ( *cp ) {
  898.             if ( i > MAXLINE && isspace(*cp)) {
  899.                 Report( "\n");
  900.                 cp++;
  901.                 i = 0;
  902.             }
  903.             else {
  904. /*                Report(*cp++);*/
  905.                 cp++;
  906.                 i++;
  907.             }
  908.         }
  909.         Report(card);
  910.         Report(";\n");
  911.         return;
  912.     }
  913.     if ( op == OOP ) {
  914.         sprintf( (char *)theMess1, "%c\t%8.5f %8.5f;\n", card[0], p[0], p[1]);
  915.         Report((char *)theMess1);
  916.         return;
  917.     }
  918.     if ( op == SOP ) {
  919.         sprintf( (char *)theMess1, "%c\t%8.5f;\n", card[0], p[1]);
  920.         Report((char *)theMess1);
  921.         return;
  922.     }
  923.     if ( op == EOP ) {
  924.         sprintf( (char *)theMess1, "%c\t%8.5f %8.1f %8.1f", card[0], p[1], p[2], p[3]);
  925.         Report((char *)theMess1);
  926.         if ( p[4] > 0.0 ) {
  927.             sprintf( (char *)theMess1, " %8.5f;\n", p[4]);
  928.             Report((char *)theMess1);
  929.         }
  930.         else 
  931.             Report(";\n");
  932.         return;
  933.     }
  934.     if ( op == TOP ) {
  935.         sprintf( (char *)theMess1, "%c\t", card[0]);    Report((char *)theMess1);
  936.         n = 1;
  937.         for ( i = 0; i < nargs; i++) {
  938.             sprintf( (char *)theMess1, " %8.5f", *(tparams[n_T_cards-1]+i));    Report((char *)theMess1);
  939.             n++;
  940.             if ( n % 8 == 0 ) {
  941.                 if ( i < nargs-1) {
  942.                     Report("\n");
  943.                     Report("\t ");
  944.                 }
  945.             }
  946.         }
  947.         Report(";\n");
  948.         return;
  949.     }
  950.  
  951.     sprintf( (char *)theMess1, "%c\t", card[0]);    Report((char *)theMess1);
  952.     n = 1;
  953.     for ( i = 0; i < nargs; i++) {
  954.         if ( i != 1 ) { /* skip instrument number (not yet calculated anyway! */
  955.             sprintf( (char *)theMess1, " %8.5f", p[i]);    Report((char *)theMess1);
  956.             n++;
  957.             if ( n % 8 == 0 ) {
  958.                 if ( i < nargs-1) {
  959.                     Report("\n");
  960.                     Report("\t ");
  961.                 }
  962.             }
  963.         }
  964.     }
  965.     Report(";\n");
  966. }    /* report1 */
  967.  
  968.  
  969.  
  970. Event *insert_in_list(op, nargs, a, b)
  971.     double    a[];
  972.     int        op;
  973.     int        nargs;
  974.     Event    *b;
  975. {
  976. /*
  977. * Merge event a chronologically into list b.
  978. */
  979.     Event *head, *cursor, *prev, *temp;
  980.     int i;
  981.     int done = 0;
  982.     double s1, s2;
  983.  
  984.     temp = (Event *)NewPtr(sizeof(Event));
  985.     if ( (errnum = MemError())  != noErr ){
  986.         PstringCopy((char *)theMess1,"\pError allocating memory in insert_in_list");
  987.         OSError(theMess1, NIL, NIL);
  988.     }
  989.     temp->nargs = nargs;
  990.     temp->op = op;
  991.     temp->next = NIL;
  992.     temp->pptr = (double *)NewPtr(temp->nargs * sizeof(double));
  993.     if ( (errnum = MemError())  != noErr ){
  994.         PstringCopy((char *)theMess1,"\pError allocating memory for parameters in insert_in_list");
  995.         OSError(theMess1, NIL, NIL);
  996.     }
  997.     for (i = 0; i<temp->nargs; i++) {
  998.         *(temp->pptr+i) = a[i];
  999.         /*sprintf( (char *)theMess1, "*(temp->pptr+i) = %f\n", *(temp->pptr+i));*/
  1000.     }
  1001.  
  1002.     head = b;
  1003.     if (!head) {
  1004.         head = temp;
  1005.         head->next = NIL;
  1006.     }
  1007.     else {
  1008.         done = 0;
  1009.         prev = cursor = head;
  1010.         while (cursor != NIL && !done ) {
  1011. /* this rats nest because i cards use different pnums for timing */
  1012. /*            if ( temp->op == IOP || temp->op == EOP)*/
  1013.             if ( temp->op == IOP)
  1014.                 s1 = *(temp->pptr+2);
  1015.             else if ( temp->op == SOP )
  1016.                 s1 = *(temp->pptr);
  1017.             else
  1018.                 s1 = *(temp->pptr+1);
  1019.  
  1020.             if ( cursor->op == IOP )
  1021.                 s2 = *(cursor->pptr+2);
  1022.             else if ( cursor->op == SOP )
  1023.                 s2 = *(cursor->pptr);
  1024.             else
  1025.                 s2 = *(cursor->pptr+1);
  1026.                 
  1027.             if ( s1 < s2 ) {
  1028.                 if (cursor == head) {
  1029.                     /* insert before head */
  1030.                     temp->next = head;
  1031.                     head = temp;
  1032.                     done = 1;
  1033.                 }
  1034.                 else {
  1035.                     temp->next = prev->next;
  1036.                     prev->next = temp;
  1037.                     done = 1;
  1038.                 }
  1039.             }
  1040.             else
  1041.                 prev = cursor;
  1042.             cursor = cursor->next;
  1043.         }
  1044.         if (!done) {
  1045.             prev->next = temp;
  1046.             temp->next = NIL;
  1047.         }
  1048.     }
  1049.     return(head);
  1050. }
  1051.  
  1052.  
  1053. void    check_list(list)
  1054.     Event *list;
  1055. {
  1056.     /* prints event list to reportfile for debugging purposes */
  1057.  
  1058.     register int i;
  1059.     register int n;
  1060.     Event *cursor;
  1061.  
  1062.     if ( !out2_flag)
  1063.         return;
  1064.     cursor = list;
  1065.     while ( cursor != NIL ) {
  1066.         n = 0;
  1067.         sprintf( (char *)theMess1, "%d", cursor->op);    Report((char *)theMess1);
  1068.         sprintf( (char *)theMess1, " %d", cursor->nargs);    Report((char *)theMess1);
  1069.         for ( i = 0; i< cursor->nargs; i++) {
  1070.             n++;
  1071.             sprintf( (char *)theMess1, " %8.3f", *(cursor->pptr+i));    Report((char *)theMess1);
  1072.             if ( n % 8 == 0 ) {
  1073.                 if ( i < cursor->nargs-1) {
  1074.                     Report("\n");
  1075.                     Report("\t");
  1076.                 }
  1077.             }
  1078.         }
  1079.         Report("\n");
  1080.         cursor = cursor->next;
  1081.     }
  1082.         Report("end of list\n");
  1083. }    /* check_list */
  1084.  
  1085.  
  1086. void    add_end_ops(list)
  1087.     Event *list;
  1088. {
  1089. /* insert ENDOP cards in chronological order in list */
  1090.     Event *cursor, *prev, *temp, *cnext;
  1091.     int done;
  1092.     double s1, s2;
  1093.  
  1094.     cursor = list;
  1095.     while ( cursor != NIL ) {
  1096.         if ( cursor->op == IOP ) {
  1097.             temp = (Event *)NewPtr(sizeof(Event));
  1098.             if ( (errnum = MemError())  != noErr ){
  1099.                 PstringCopy((char *)theMess1,"\pError allocating memory in add_end_ops");
  1100.                 OSError(theMess1, NIL, NIL);
  1101.             }
  1102.             temp->nargs = 3;
  1103.             temp->op = ENDOP;
  1104.             temp->next = NIL;
  1105.             temp->pptr = (double *)NewPtr(temp->nargs * sizeof(double));
  1106.             if ( (errnum = MemError())  != noErr ){
  1107.                 PstringCopy((char *)theMess1,"\pError allocating memory for parameters in add_end_op");
  1108.                 OSError(theMess1, NIL, NIL);
  1109.             }
  1110.             *(temp->pptr) = *(cursor->pptr);
  1111.             *(temp->pptr+1) = *(cursor->pptr+1);
  1112.             *(temp->pptr+2) = *(cursor->pptr+2) + *(cursor->pptr+3);
  1113.             done = 0;
  1114.             prev = cursor;
  1115.             cnext = cursor->next;
  1116.             if ( temp->op == IOP || temp->op == ENDOP)
  1117.                 s1 = *(temp->pptr+2);
  1118.             else
  1119.                 s1 = *(temp->pptr+1);
  1120.  
  1121.             while (cnext != NIL && !done ) {
  1122.                 if ( cnext->op == IOP || cnext->op == ENDOP)
  1123.                     s2 = *(cnext->pptr+2);
  1124.                 else
  1125.                     s2 = *(cnext->pptr+1);
  1126.                 if ( cnext->op == SOP || cnext->op == EOP ) {
  1127.                     temp->next = prev->next;
  1128.                     prev->next = temp;
  1129.                     done = 1;
  1130.                 }
  1131.                 else if ( s1 <= s2 ) {
  1132.                     /* ensure functions preceed notes for same action time */
  1133.                     if ( cnext->op != FOP ) {
  1134.                         temp->next = prev->next;
  1135.                         prev->next = temp;
  1136.                         done = 1;
  1137.                     }
  1138.                 }
  1139.                 else
  1140.                     prev = cnext;
  1141.                 cnext = cnext->next;
  1142.                 
  1143.             }
  1144.             if (!done) {
  1145.                 prev->next = temp;
  1146.             }
  1147.         }
  1148.         cursor = cursor->next;
  1149.     }
  1150. }
  1151. /*-------------------------------------------------------------------------------*/
  1152. double
  1153. myAtof(cp)
  1154.     char    *cp;
  1155. {
  1156. /* to overcome problem of atof() no converting leading zeros correctly */
  1157.     register    i;
  1158.     double    theDouble;
  1159.     char    *leadingZero;
  1160.     Boolean    eoNumber;
  1161.     
  1162.     
  1163.     eoNumber = FALSE;
  1164.     i = 0;
  1165.     leadingZero = cp;
  1166. Start:
  1167.     while (isspace(*leadingZero)) {
  1168.         if ( !*leadingZero ) {
  1169.             eoNumber = TRUE;
  1170.             break;
  1171.         }
  1172.         leadingZero++;
  1173.     }
  1174.  
  1175.     if ( *leadingZero ) {    
  1176.         switch ( *leadingZero ) {
  1177.             case '1':
  1178.             case '2':
  1179.             case '3':
  1180.             case '4':
  1181.             case '5':
  1182.             case '6':
  1183.             case '7':
  1184.             case '8':
  1185.             case '9':
  1186.                 theDouble = atof(cp);
  1187.                 return(theDouble);
  1188.                 break;
  1189.             case '+':
  1190.             case '-':
  1191.                 leadingZero++;
  1192.                 goto Start;
  1193.             case '.':
  1194.             case '0':
  1195.                 break;
  1196.             default:
  1197.                 break;
  1198.         }
  1199.     }
  1200.     
  1201.     while (!eoNumber && *leadingZero != '.') {
  1202.         if ( !*leadingZero ) {
  1203.             eoNumber = TRUE;
  1204.             break;
  1205.         }
  1206.         else if ( *leadingZero == ' ') {
  1207.             eoNumber = TRUE;
  1208.             break;
  1209.         }
  1210.         else {
  1211.             leadingZero++;
  1212.             i++;
  1213.         }
  1214.         switch ( *leadingZero ) {
  1215.             case '1':
  1216.             case '2':
  1217.             case '3':
  1218.             case '4':
  1219.             case '5':
  1220.             case '6':
  1221.             case '7':
  1222.             case '8':
  1223.             case '9':
  1224.                 eoNumber = TRUE;
  1225.                 break;
  1226.         }
  1227.     }
  1228.     /* we have a '.', see if there are any 0s following, before a digit */
  1229.     i = 0;
  1230.     if ( !eoNumber ) {
  1231.         leadingZero++;
  1232.         while (*leadingZero == '0') {
  1233.             leadingZero++;
  1234.             i++;
  1235.         }
  1236.     }
  1237.     theDouble = atof(cp);
  1238.     while ( i > 0 ) {
  1239.         theDouble /= 10.0;
  1240.         i--;
  1241.     }
  1242.     return(theDouble);
  1243. }
  1244.